/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package eu.marc.juliator.gui.io;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import uk.ac.ebi.pride.tools.braf.BufferedRandomAccessFile;

/**
 * This class takes a text file as input and allows its usage like a table
 *
 * @author Marc
 */
public class InputFile {

    /**
     * the input file
     */
    private BufferedRandomAccessFile bufferedRandomAccessFile = null;
    /**
     * The column separator
     */
    private String separator;
    /**
     * A line to index map
     */
    private HashMap<Integer, Long> lineToIndexMap = new HashMap<Integer, Long>();
    /**
     * The maximal number of columns
     */
    private int nColumns = 0;
    /**
     * The number of lines
     */
    private int nLines;

    /**
     * Constructor
     *
     * @param inputFile the text file to parse
     * @param separator the separator used to separate columns
     */
    public InputFile(File inputFile, String separator) throws IOException {
        this.separator = separator;
        indexFile(inputFile);
    }

    /**
     * Loads a text file in the model
     *
     * @param aFile
     * @throws IOException
     */
    private void indexFile(File aFile) throws IOException {
        bufferedRandomAccessFile = new BufferedRandomAccessFile(aFile, "r", 1024 * 100);

        String line;
        nLines = 0;
        long index = bufferedRandomAccessFile.getFilePointer();
        while ((line = bufferedRandomAccessFile.readLine()) != null) {
            lineToIndexMap.put(nLines, index);
            if (nLines == Integer.MAX_VALUE) {
                throw new IllegalArgumentException("Your file reached the maximal input capacity: " + Integer.MAX_VALUE + ", please contact the developer.");
            }
            nLines++;
            index = bufferedRandomAccessFile.getFilePointer();
            nColumns = Math.max(nColumns, line.split(separator).length);
        }
    }

    /**
     * Returns the element at position column at line lineNumber in the text
     * file indexed
     *
     * @param lineNumber
     * @param column
     * @return
     * @throws IOException
     */
    public String getValueAt(int lineNumber, int column) throws IOException {
        Long index = lineToIndexMap.get(lineNumber);
        if (index != null) {
            bufferedRandomAccessFile.seek(index);
            String line = bufferedRandomAccessFile.readLine();
            String[] splittedLine = line.split(separator);
            if (splittedLine.length > column && column >= 0) {
                return splittedLine[column];
            } else {
                return "";
            }
        }
        return "";
    }
    
    /**
     * Returns the value at a given line
     * @param lineNumber
     * @return
     * @throws IOException 
     */
    public String getLineAt(int lineNumber) throws IOException {
        Long index = lineToIndexMap.get(lineNumber);
        if (index != null) {
            bufferedRandomAccessFile.seek(index);
            return bufferedRandomAccessFile.readLine();
        }
        return "";
    }

    /**
     * Returns the number of columns
     *
     * @return
     */
    public int getNColumns() {
        return nColumns;
    }

    /**
     * Returns the number of lines
     *
     * @return
     */
    public int getNLines() {
        return nLines;
    }

    /**
     * Closes the connection to the file
     */
    public void close() throws IOException {
        bufferedRandomAccessFile.close();
    }
}
